package com.mybatis.boost.generator.util;

import com.google.common.base.Splitter;
import com.mybatis.boost.generator.java.Annotation;
import com.mybatis.boost.tool.OptionalExt;
import lombok.NonNull;
import org.mybatis.generator.api.dom.java.Field;

import java.util.Map;
import java.util.Set;

import static java.util.stream.Collectors.toSet;

/**
 * @author jearton
 * @since 2017/2/4
 */
public abstract class GeneratorUtil {

    public static Set<Annotation> parseAnnotations(@NonNull Field field) {
        return field.getAnnotations().stream().map(annotationStr -> {
            String name;
            if (annotationStr.contains("(")) {
                name = annotationStr.substring(0, annotationStr.indexOf("("));
            } else {
                name = annotationStr;
            }
            int startIndex = annotationStr.indexOf("(");
            if (startIndex < 0) {
                return new Annotation(name);
            }
            String propertiesStr = annotationStr.substring(startIndex + 1, annotationStr.lastIndexOf(")"));
            return new Annotation(name, Splitter.on(",").withKeyValueSeparator("=").split(propertiesStr));
        }).collect(toSet());
    }

    public static void addOrUpdateAnnotation(@NonNull Field field, @NonNull String name, @NonNull Map<String, String> properties) {
        Annotation newAnnotation = new Annotation(name, properties);
        OptionalExt.of(parseAnnotations(field).stream().filter(newAnnotation::equals).findFirst())
                .ifPresent(annotation -> {
                    annotation.getProperties().putAll(properties);
                    field.getAnnotations().removeIf(annotationStr -> annotationStr.contains(annotation.getName()));
                    field.getAnnotations().add(annotation.toString());
                })
                .orElse(() -> field.getAnnotations().add(newAnnotation.toString()));
    }

    public static void addOrUpdateAnnotation(@NonNull Field field, @NonNull String name) {
        Annotation newAnnotation = new Annotation(name);
        if (parseAnnotations(field).stream().noneMatch(newAnnotation::equals)) {
            field.getAnnotations().add(newAnnotation.toString());
        }
    }
}
